package com.junjie.checkin.service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.junjie.checkin.entity.Enum.ActivityHistoryStatusEnum;
import com.junjie.checkin.entity.Enum.ActivityStatusEnum;
import com.junjie.checkin.entity.Enum.PointRecordTypeEnum;
import com.junjie.checkin.entity.TActivity;
import com.junjie.checkin.entity.TPointRecord;
import com.junjie.checkin.entity.TStudentActivityHistory;
import com.junjie.checkin.entity.TUser;
import com.junjie.checkin.exception.ResourceNotFountException;
import com.junjie.checkin.exception.checkIn.ErrorCheckInTimeException;
import com.junjie.checkin.exception.checkIn.UserAlreadyCheckInException;
import com.junjie.checkin.exception.checkIn.UserNotSignUpException;
import com.junjie.checkin.exception.signUp.HistoryCancelledException;
import com.junjie.checkin.exception.signUp.SignUpCountMaxException;
import com.junjie.checkin.exception.signUp.SignUpErrorException;
import com.junjie.checkin.exception.signUp.UserAlreadySignUpException;
import com.junjie.checkin.mapper.ActivityMapper;
import com.junjie.checkin.mapper.PointRecordMapper;
import com.junjie.checkin.mapper.StudentActivityHistoryMapper;
import com.junjie.checkin.mapper.UserMapper;
import com.junjie.checkin.request.activity.ActivityPageRequest;
import com.junjie.checkin.response.*;
import com.junjie.checkin.response.admin.ActivityDetailsResponse;
import com.junjie.checkin.response.admin.ActivityResponse;
import com.junjie.checkin.response.front.ActivityDetailsFrontResponse;
import com.junjie.checkin.response.front.ActivityFrontResponse;
import com.junjie.checkin.response.front.UserActivityHistoryResponse;
import com.junjie.checkin.security.service.AuthDetails;
import com.junjie.checkin.security.service.JwtService;
import com.junjie.checkin.security.service.impl.JwtServiceImpl;
import com.junjie.checkin.utils.DateTimeFormat;
import com.junjie.checkin.websocket.entity.StompMessage;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.simp.SimpMessagingTemplate;
import org.springframework.stereotype.Service;

import java.util.Objects;

@Service
public class ActivityService {
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private ActivityMapper activityMapper;
    @Autowired
    private PointRecordMapper pointRecordMapper;
    @Autowired
    JwtServiceImpl jwtService;
    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;

    @Autowired
    private StudentActivityHistoryMapper activityHistoryMapper;

    /**
     * 获取活动列表
     * @param activityPageRequest 查询参数
     * @return 分页结果
     */
    public PageResult<ActivityFrontResponse> getActivities(ActivityPageRequest activityPageRequest, String token) {
        Integer id = jwtService.analyzeToken(token).getUser().getId();
        PageHelper.startPage(activityPageRequest.getPage(), activityPageRequest.getPageSize());
        Page<ActivityFrontResponse> page = activityMapper.pageQueryWithParticipantCountAndParticipation(activityPageRequest.getTitle(),activityPageRequest.getType(),activityPageRequest.getStatus(),id);
        return new PageResult<>(page.getTotal(), page.getResult());
    }

    /**
     * 获取用户已报名的活动列表
     * @param token 用户令牌
     * @param pageRequest 查询参数
     * @return 分页结果
     */
    public PageResult<UserActivityHistoryResponse> getParticipatedActivities(String token, ActivityPageRequest pageRequest){
        Integer id = jwtService.analyzeToken(token).getUser().getId();
        PageHelper.startPage(pageRequest.getPage(), pageRequest.getPageSize());
        Page<UserActivityHistoryResponse> page = activityMapper.pageQueryUserParticipatedActivities(id, pageRequest.getTitle(), pageRequest.getType(), pageRequest.getStatus());
        return new PageResult<>(page.getTotal(), page.getResult());
    }


    /**
     * 获取活动详情 (已完成修改)
     * @param id 活动id
     * @return 活动详细数据
     */
    public ActivityDetailsResponse getActivityById(Integer id, String token) {
        TActivity activity = activityMapper.selectById(id);
        // 检查活动是否存在
        if (activity == null){
            throw new ResourceNotFountException();
        }
        // 检查用户状态是否处于有效状态
        if (activity.getStatus()== ActivityStatusEnum.DRAFT || activity.getStatus()== ActivityStatusEnum.CANCELED){
            throw new ResourceNotFountException();
        }

        // 获取用户ID

        Integer userId = jwtService.analyzeToken(token).getUser().getId();
        TStudentActivityHistory history = activityHistoryMapper.checkUserParticipated(id, userId);
        ActivityDetailsResponse detailsResponse = new ActivityDetailsFrontResponse(!Objects.isNull(history),!Objects.isNull(history)?history.getStatus():null);

        // 转换对象
        BeanUtils.copyProperties(activity,detailsResponse);
        // 格式化日期
        detailsResponse.setStartTime(DateTimeFormat.dateToString(activity.getStartTime()));
        detailsResponse.setEndTime(DateTimeFormat.dateToString(activity.getEndTime()));
        detailsResponse.setCreateTime(DateTimeFormat.dateToString(activity.getCreateTime()));
        detailsResponse.setUpdateTime(DateTimeFormat.dateToString(activity.getUpdateTime()));
        // 获取参与人数
        Integer activityParticipants = activityHistoryMapper.getActivityParticipants(activity.getId());
        detailsResponse.setCurrentParticipants(activityParticipants);

        return detailsResponse;
    }

    /**
     * 报名活动
     * @param id 活动ID
     * @param token 用户令牌
     */
    public void signUpActivity(Integer id,String token) {
        TActivity activity = activityMapper.selectById(id);
        // 检查活动是否存在
        if (Objects.isNull(activity)){
            throw  new ResourceNotFountException();
        }
        // 检查活动是在未开始阶段
        if (activity.getStatus() != ActivityStatusEnum.PUBLISHED){
            throw new SignUpErrorException();
        }
        // 获取当前的用户信息
        AuthDetails authDetails = jwtService.analyzeToken(token);
        TUser user = authDetails.getUser();

        // 检查用户是否已经报名
        if(!Objects.isNull(activityHistoryMapper.checkUserParticipated(id,user.getId()))){
            throw new UserAlreadySignUpException();
        }
        // 检查当前的活动人数是否已经达到最大值
        if (activityHistoryMapper.getActivityParticipants(id) >= activity.getMaxParticipants()){
            throw new SignUpCountMaxException();
        }

        // 填充数据到活动记录中
        TStudentActivityHistory history = new TStudentActivityHistory();
        history.setActivityId(id);
        history.setUserId(user.getId());
        history.setActivityName(activity.getTitle());
        history.setActivityTime(DateTimeFormat.dateToString(activity.getStartTime()));
        history.setStudentName(user.getNickname());
        history.setPoint(activity.getPoint());
        history.setStatus(ActivityHistoryStatusEnum.REGISTERED);
        activityHistoryMapper.insert(history);
    }

    /**
     * 签到活动
     * @param id 活动ID
     * @param token  当前用户令牌
     */
    public void checkInActivity(Integer id,String token){
        //获取当前用户信息
        Integer userId = jwtService.analyzeToken(token).getUser().getId();
        TUser user = userMapper.selectById(userId);
        //检查活动是否存在
        TActivity activity = activityMapper.selectById(id);
        if (Objects.isNull(activity)){
            throw new ResourceNotFountException();
        }
        //检查当前用户是否报名该活动
        TStudentActivityHistory history = activityHistoryMapper.checkUserParticipated(id,userId);
        if (Objects.isNull(history)){
            throw new UserNotSignUpException();
        }
        //检查当前时间是否在活动时间段内
        if (!DateTimeFormat.isCurrentTimeInInterval(activity.getStartTime(),activity.getEndTime())){
            throw new ErrorCheckInTimeException();
        }
        //检查用户是否已经签到 TODO 这边逻辑有问题,需要处理
        if (history.getStatus().equals(ActivityHistoryStatusEnum.SIGN_UP)){
            throw new UserAlreadyCheckInException();
        }
        if(history.getStatus().equals(ActivityHistoryStatusEnum.CANCELLED)){
            throw new HistoryCancelledException();
        }//修改签到状态
        history.setStatus(ActivityHistoryStatusEnum.SIGN_UP);
        activityHistoryMapper.updateById(history);
        // 添加积分明细记录
        TPointRecord tPointRecord = new TPointRecord();
        tPointRecord.setUserId(userId);
        tPointRecord.setRelatedType(PointRecordTypeEnum.ACTIVITY);
        tPointRecord.setRelatedId(activity.getId());
        tPointRecord.setChangePoint(activity.getPoint());
        Integer totalPoint = user.getScore()+activity.getPoint();
        tPointRecord.setTotalPoint(totalPoint);
        tPointRecord.setRemark("签到活动:"+activity.getTitle());
        pointRecordMapper.insert(tPointRecord);
        // 更新用户积分
        user.setScore(totalPoint);
        // 构建STOMP消息
        StompMessage<TStudentActivityHistory> stompMessage = new StompMessage<>("activityCheckIn","签到数据更新",history);
        simpMessagingTemplate.convertAndSend("/topic/admin/activity",stompMessage);
        userMapper.updateById(user);
    }

}
